#ifndef COMMAND_H
#define COMMAND_H

#include <QString>
#include "baseOp.h"
#include "cardReaderDev.h"

namespace SDHuaYi_Script
{

    enum EnumCmdType
    {
        CMD_APDU = 0,
        CMD_DEFINE,
        CMD_LABEL,
        CMD_COMMENT,
        CMD_FLOW,
        CMD_EMPTY,
        CMD_DATAOP,
        CMD_INSERT,
        CMD_JUDGEMENT
    };

    enum EnumCmdResultType
    {
        CMD_RESULT_PASS = 0,
        CMD_RESULT_FAIL = 1,
        CMD_RESULT_NONE = 2,
        CMD_RESULT_WARNING = 3,
        CMD_PC_CHANGE,
        CMD_FORMAT_ERR,
    };

    class CommandResult
    {
    public:
        EnumCmdResultType ResultType = CMD_RESULT_NONE;
        QString ResultMessage;

        CommandResult()
        {
            ResultType = CMD_RESULT_NONE;
            ResultMessage.clear();
        }
    };

    class command
    {
    private:
        const qint32 ROOM_32K = 5;
        const qint32 ROOM_16K = 4;
        const qint32 ROOM_8K = 3;
        const qint32 ROOM_4K = 2;
        const qint32 ROOM_2K = 1;

    public:
        EnumCmdType Type = CMD_APDU;
        /* 卡片类型 188D、other*/
        QString sCardType = NULL;
        /* 内部变量 */
        QString sExptATS = NULL;
        /* 命令字符串 */
        QString cmdStr = NULL;
        /* 命令值 */
        QString Value = NULL;
        /* 命令开始在脚本中的位置 */
        qint32 startIndex = 0;
        /* 期望返回 */
        QString ExptRe = NULL;
        /* 注释 */
        QString Comment = NULL;
        /* 命令返回数据 */
        QString Response = NULL;
        /* 命令返回SW */
        QString SW = NULL;

        // TODO:此部分暂不去做兼容
        // //V6COS数据文件
        // public QString[] sBinFileContents = null;
        // public qint32 iBinLen = 0;
        // //V6COS配置信息
        // public QList<Para> V6CosInfo = new QList<Para>();
        // //320XCOS配置信息
        // public QList<Para> X320CosInfo = new QList<Para>();
        // public QString X320BinFileContents = QString.Empty;
        // public QString sPatchMod = QString.Empty;//patch模式
        // public QString sPathStaD = QString.Empty;//PATCH起始地址
        // public QString[] sDIYCmds = new QString[50];

        /* 记录LOG */
        QString sLOG = NULL;

        /* 记录uid和认证码 */
        QString sUID = NULL;
        QString sAuth = NULL;

        /* 读卡器调用接口 */
        cardReaderDev m_Reader = {};

        /* Command的返回值 */
        CommandResult cmdResult = CommandResult();

    private:
        BaseOP BOP = BaseOP();
        // TODO:暂不支持RSA加密
        //  RSA rsa = new RSA();
        HY_RSA_PUBLIC_KEY hY_RSA_PUBLIC_KEY = {};

    public:
        /* 构造函数 */
        command();
        command(QString value, EnumCmdType type) : Value(value), Type(type) {}
        command(QString value, qint32 startindex, EnumCmdType type) : Value(value), startIndex(startindex), Type(type) {}
        // 拷贝构造函数
        command(const command &other) : Type(other.Type), sCardType(other.sCardType), sExptATS(other.sExptATS), cmdStr(other.cmdStr),
                                        Value(other.Value), startIndex(other.startIndex), ExptRe(other.ExptRe), Comment(other.Comment), Response(other.Response),
                                        SW(other.SW), sLOG(other.sLOG), sUID(other.sUID), sAuth(other.sAuth) {}
        // 拷贝赋值运算
        command &operator=(const command &other)
        {
            if (this != &other)
            {
                Type = other.Type;
                sCardType = other.sCardType;
                sExptATS = other.sExptATS;
                cmdStr = other.cmdStr;
                Value = other.Value;
                startIndex = other.startIndex;
                ExptRe = other.ExptRe;
                Comment = other.Comment;
                Response = other.Response;
                SW = other.SW;
                sLOG = other.sLOG;
                sUID = other.sUID;
                sAuth = other.sAuth;
            }
            return *this;
        }

    public:
        /* 检查是否是判断语句 */
        bool isCmdJudge(QString cmdValue);

        /* 检查命令是否为赋值命令 */
        bool isCmdSetData(QString cmdValue);

        /* 处理数学运算 只支持 inter类型 */
        void MathProcess(QString &cmdValue);

        /* 处理 赋值、判断、显示等命令 */
        QString Excute(QString cmdValue, QList<Para> &paras, HY_RSA_PUBLIC_KEY hY_RSA_PUBLIC_KEY = {});

        /* 执行读卡器相关命令 */
        QString Excute(cardReaderDev inputReader, QList<Para> &paras, HY_RSA_PUBLIC_KEY hY_RSA_PUBLIC_KEY = {});

        /* 处理过程关键字 */
        qint32 Process_Excu(QList<Para> &paras, QString sCMD);

        /* 格式处理 */
        void Format(QString &sCMD);

        /* 括号配对,核心代码 */
        qint32 BracketMatch(QString &sCMD);

        /* 关键字公式计算 */
        QString KeyWordTable(QString sCmdHeader, QStringList sPara = {});

        // private:
        /* 检查是否是操作符 */
        bool isOpr(QString oper);

        /* 检查是否为立即数 */
        QString FormatToDataInteger(QString data);

        /* 替换命令中的立即数 */
        bool IntegerReplace(QString &str);

        /* 替换指令中的变量 */
        qint32 Assignment(QString &sDataIn, QList<Para> &para);

        /* 不含计算的赋值语句处理流程 */
        void Equals_Process(QString sDataIn, QList<Para> &para);

        /* DATA_ENC */
        QString DATA_ENC_Process(QString value, QString key);

        /* DATA_DEC */
        QString DATA_DEC_Process(QString value, QString key);

        /* ENC */
        QString ENC_Process(QString value, QString key);

        /* DEC */
        QString DEC_Process(QString value, QString key);

        /* mac */
        QString MAC_Process(QString value, QString key, QString challange);

        /* RSA公钥加密 */
        QString RSA_PUB_ENC_Process(QString sInPutData);

        /* 设置公钥模 */
        qint32 RSA_PUBKEY_SET_Process(QString sInPutData);

        /* 设置公钥指数 */
        qint32 RSA_PUBEXP_SET_Process(QString sInPutData);

        /* mid */
        QString Mid_Process(QString sDataIn, QString sStart, QString sLen);

        /* left */
        QString Left_Process(QString sDataIn, QString sLen);

        /* Right */
        QString Right_Process(QString sDataIn, QString sLen);

        /* Len */
        qint32 Len_Process(QString sDataIn);

        /* strxor */
        QString STRXOR_Process(QString sDataIn1, QString sDataIn2);

        /* stror */
        QString STROR_Process(QString sDataIn1, QString sDataIn2);

        /* STRAND */
        QString STRAND_Process(QString sDataIn1, QString sDataIn2);

        /* STRADD */
        QString STRADD_Process(QString sDataIn1, QString sDataIn2);

        /* STRSUB */
        QString STRSUB_Process(QString sDataIn1, QString sDataIn2);

        /* 字符串取反 */
        QString INVERSE_Process(QString sDataIn);

        /* XOR异或 */
        QString XOR_Process(QString sDateIn);

        /* 返回目标整数值的字符串形式 */
        QString ITOA_Process(QString sDataIn);

        /* 返回目标整数值的字符串形式 */
        QString ATOI_Process(QString sDataIn);

    private:
        /* 单独处理指令发送流程 */
        void SendAPDU(QString sCMD, QList<Para> &paras, QString sExSW = "9000");
    };
}
#endif // COMMAND_H
